{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 汉明重量幅度\n",
    "\n",
    "支持的设备:\n",
    "\n",
    "SCOPES:\n",
    "\n",
    "* OPENADC\n",
    "* CWNANO\n",
    "\n",
    "PLATFORMS:\n",
    "\n",
    "* CWLITEARM\n",
    "* CWLITEXMEGA\n",
    "* CWNANO"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "SCOPETYPE = 'OPENADC'\n",
    "PLATFORM = 'CWLITEARM'\n",
    "CRYPTO_TARGET = 'TINYAES128C'\n",
    "num_traces = 50"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash -s \"$PLATFORM\" \"$CRYPTO_TARGET\"\n",
    "cd ../../hardware/victims/firmware/simpleserial-aes\n",
    "make PLATFORM=$1 CRYPTO_TARGET=$2"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据追踪理论\n",
    "\n",
    "在上一个教程中，我们看到一个设备的功率测量是如何与汉明重量相关的。让我们用这个来看看一些任意的数据在哪里被设备处理。稍后我们将在此基础上扩展，考虑一些随机数据和噪音的情况。\n",
    "\n",
    "我们的目标很简单——我们将在一个地方发送一些全部为1的数据，然后再发送一些全部为0的数据。"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 捕获能力轨迹"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "捕获功率跟踪将与以前的教程非常相似，只是这次我们将使用一个循环来捕获多个跟踪，以及使用numpy来存储这些跟踪。"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 设置"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们将使用一些辅助脚本来使设置和编程更容易。如果你使用的是XMEGA或STM（CWLITEARM）目标，带有正确的二进制文件应该为你设置。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%run \"../Helper_Scripts/Setup_Generic.ipynb\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fw_path = '../../hardware/victims/firmware/simpleserial-aes/simpleserial-aes-{}.hex'.format(PLATFORM)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# program the target\n",
    "cw.program_target(scope, prog, fw_path)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 捕获轨迹"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下面你可以看到捕获循环。循环的主体加载一些新的明文，设置域端，发送密钥和明文，然后最后记录并将我们的新跟踪附加到`traces[]`列表中。在最后，我们将跟踪数据转换为numpy数组。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Capture Traces\n",
    "from tqdm import tnrange\n",
    "import numpy as np\n",
    "import time\n",
    "\n",
    "ktp = cw.ktp.Basic()\n",
    "\n",
    "traces = []\n",
    "\n",
    "for i in tnrange(num_traces, desc='Capturing traces'):\n",
    "    key, text = ktp.next()\n",
    "    \n",
    "    #Currently ALL bits are random. Let's extend bit 0 to a full byte to give us a random 0xFF or 0x00\n",
    "    if text[0] & 0x01:\n",
    "        text[0] = 0xFF\n",
    "    else:\n",
    "        text[0] = 0x00\n",
    "    \n",
    "    trace = cw.capture_trace(scope, target, text, key)\n",
    "    if trace is None:\n",
    "        continue\n",
    "    traces.append(trace)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "现在我们有了我们的轨迹，我们也可以用Bokeh绘制它们："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bokeh.plotting import figure, show\n",
    "from bokeh.io import output_notebook\n",
    "\n",
    "output_notebook()\n",
    "p = figure()\n",
    "\n",
    "xrange = range(len(traces[0].wave))\n",
    "p.line(xrange, traces[2].wave, line_color=\"red\")\n",
    "show(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# cleanup the connection to the target and scope\n",
    "scope.dis()\n",
    "target.dis()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 轨迹分析"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 比较0xFF和0x00"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "现在我们有了一些轨迹，让我们看看我们实际记录了什么。我们将做以下工作：\n",
    "\n",
    "1. 将轨迹分到两组：0x00和0xFF\n",
    "2. 计算每组的平均值。\n",
    "3. 减去这两个平均数，看看有什么不同。\n",
    "\n",
    "这将显示在以下两个单元格中。注意0xFF和0x00的数量并不完全是50/50。这就是为什么我们需要确保对它们进行平均。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bokeh.plotting import figure, show\n",
    "from bokeh.io import output_notebook\n",
    "import numpy as np\n",
    "\n",
    "output_notebook()\n",
    "p = figure()\n",
    "\n",
    "one_list = []\n",
    "zero_list = []\n",
    "\n",
    "for trace in traces:\n",
    "    if trace.textin[0] == 0x00:\n",
    "        one_list.append(trace.wave)\n",
    "    else:\n",
    "        zero_list.append(trace.wave)\n",
    "\n",
    "print(\"Number of 0xFF: \" + str(len(one_list)))\n",
    "print(\"Number of 0x00: \" + str(len(zero_list)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "one_avg = np.asarray(one_list).mean(axis=0)\n",
    "zero_avg = np.asarray(zero_list).mean(axis=0)\n",
    "\n",
    "diff = one_avg - zero_avg\n",
    "p.line(range(0, len(traces[0].wave)), diff)\n",
    "show(p)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "显然我们可以看到一个尖峰数据，这说明了HW值的影响幅度。如果你有时间，你也可以尝试以下一些方法：\n",
    "\n",
    "* 强制输出数据都为0xFF或都为0x00s\n",
    "* 强制一些中间值都为0xFF或都为0x00s\n",
    "* 设置多个字节为0xFF或0x00\n",
    "* 按顺序绘制每个字节，以查看数据移动情况"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.9.12 64-bit",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.9.12 (main, Mar 26 2022, 15:51:13) \n[Clang 12.0.0 (clang-1200.0.32.29)]"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
